package com.czl.module_storehouse.widget.picker;

import static com.czl.module_storehouse.widget.picker.Const.INDEX_INVALID;
import static com.czl.module_storehouse.widget.picker.Const.INDEX_TAB_AREA;
import static com.czl.module_storehouse.widget.picker.Const.INDEX_TAB_CITY;
import static com.czl.module_storehouse.widget.picker.Const.INDEX_TAB_PROVINCE;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

import androidx.annotation.IntDef;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;


import com.czl.module_storehouse.R;
import com.czl.module_storehouse.bean.CityBean;
import com.czl.module_storehouse.bean.DistrictBean;
import com.czl.module_storehouse.bean.ProvinceBean;
import com.czl.module_storehouse.widget.picker.Interface.OnCityItemClickListener;
import com.czl.module_storehouse.widget.picker.citywheel.CityParseHelper;
import com.czl.module_storehouse.widget.picker.utils.PickerUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;


public class CityPicker {

    /**
     * 未知状态
     */
    public static final int VIEW_STATE_UNKNOWN = -1;
    /**
     * 内容视图
     */
    public static final int VIEW_STATE_CONTENT = 0;
    /**
     * 加载失败
     */
    public static final int VIEW_STATE_ERROR = 1;
    /**
     * 数据为空
     */
    public static final int VIEW_STATE_EMPTY = 2;
    /**
     * 加载中
     */
    public static final int VIEW_STATE_LOADING = 3;

    public static final int REQUEST_TYPE_PROVINCE = 0;
    public static final int REQUEST_TYPE_CITY = 1;
    public static final int REQUEST_TYPE_DISTRICT = 2;

    private ListView mCityListView;

    private TextView mProTv;

    private TextView mCityTv;

    private TextView mAreaTv;
    private ImageView mCloseImg;

    private PopupWindow popwindow;
    private View mSelectedLine;
    private View popview;

    private CityParseHelper parseHelper;
    private ProvinceAdapter mProvinceAdapter;
    private CityAdapter mCityAdapter;
    private AreaAdapter mAreaAdapter;

    private List<ProvinceBean> provinceList = null;
    private List<CityBean> cityList = null;
    private List<DistrictBean> areaList = null;

    private int tabIndex = INDEX_TAB_PROVINCE;
    private Context context;
    private String colorSelected = "#ff181c20";
    private String colorAlert = "#ffff4444";

    private OnCityItemClickListener mBaseListener;
    private OnRequestListener mOnRequestListener;
    private CityConfig cityConfig = null;
    //加载中
    private View mLoadingView;
    //加载失败
    private View mErrorView;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({VIEW_STATE_UNKNOWN, VIEW_STATE_CONTENT, VIEW_STATE_ERROR, VIEW_STATE_EMPTY, VIEW_STATE_LOADING})
    public @interface ViewState {
    }

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({REQUEST_TYPE_PROVINCE, REQUEST_TYPE_CITY, REQUEST_TYPE_DISTRICT})
    public @interface RequestType {
    }

    @ViewState
    private int mViewState;

    @ViewState
    public int getViewState() {
        return mViewState;
    }

    public void setViewState(@ViewState int viewState) {
        mViewState = viewState;
        switch (mViewState) {
            case VIEW_STATE_LOADING:
                if (mLoadingView != null) {
                    mLoadingView.setVisibility(View.VISIBLE);
                }
                if (mCityListView != null) {
                    mCityListView.setVisibility(View.GONE);
                }
                if (mErrorView != null) {
                    mErrorView.setVisibility(View.GONE);
                }
                break;
            case VIEW_STATE_ERROR:
                if (mErrorView != null) {
                    mErrorView.setVisibility(View.VISIBLE);
                }
                if (mLoadingView != null) {
                    mLoadingView.setVisibility(View.GONE);
                }
                if (mCityListView != null) {
                    mCityListView.setVisibility(View.GONE);
                }
                break;
            case VIEW_STATE_EMPTY:
                break;
            case VIEW_STATE_CONTENT:
                if (mLoadingView != null) {
                    mLoadingView.setVisibility(View.GONE);
                }
                if (mErrorView != null) {
                    mErrorView.setVisibility(View.GONE);
                }
                if (mCityListView != null) {
                    mCityListView.setVisibility(View.VISIBLE);
                }
                break;
            case VIEW_STATE_UNKNOWN:
                break;
        }
    }

    public void setOnCityItemClickListener(OnCityItemClickListener listener) {
        mBaseListener = listener;
    }

    public void setConfig(CityConfig cityConfig) {
        this.cityConfig = cityConfig;
    }

    public void setOnRequestListener(OnRequestListener onRequestListener) {
        mOnRequestListener = onRequestListener;
    }

    private void initJDCityPickerPop(OnRequestListener onRequestListener) {

        if (this.cityConfig == null) {
            this.cityConfig = new CityConfig.Builder().setJDCityShowType(CityConfig.ShowType.PRO_CITY_DIS).build();
        }

        tabIndex = INDEX_TAB_PROVINCE;
        popview = View.inflate(context, R.layout.pop_citypicker, null);
        mCityListView = popview.findViewById(R.id.city_listview);
        mLoadingView = popview.findViewById(R.id.view_loading);
//        mErrorView = popview.findViewById(R.id.view_loading_error);
        int dataStyle = cityConfig.getDataStyle();
        if (CityConfig.DATA_LOCATION == dataStyle) {
            mCityListView.setVisibility(View.VISIBLE);
            mLoadingView.setVisibility(View.GONE);
            //解析初始数据
            if (parseHelper == null) {
                parseHelper = new CityParseHelper();
            }
            if (parseHelper.getProvinceBeanArrayList().isEmpty()) {
                return;
            }
        }
        mProTv = popview.findViewById(R.id.province_tv);
        mCityTv = popview.findViewById(R.id.city_tv);
        mAreaTv = popview.findViewById(R.id.area_tv);
        mCloseImg = popview.findViewById(R.id.close_img);
        mSelectedLine = popview.findViewById(R.id.selected_line);

        popwindow = new PopupWindow(popview, LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        popwindow.setAnimationStyle(R.style.AnimBottom);
        popwindow.setBackgroundDrawable(new ColorDrawable());
        popwindow.setTouchable(true);
        popwindow.setOutsideTouchable(false);
        popwindow.setFocusable(true);

        popwindow.setOnDismissListener(() -> PickerUtils.setBackgroundAlpha(context, 1.0f));


        mCloseImg.setOnClickListener(v -> {
            hidePop();
            PickerUtils.setBackgroundAlpha(context, 1.0f);
            if (mBaseListener != null) {
                mBaseListener.onCancel();
            }
        });

        mProTv.setOnClickListener(v -> {
            tabIndex = INDEX_TAB_PROVINCE;
            if (mProvinceAdapter != null) {
                mCityListView.setAdapter(mProvinceAdapter);
                if (mProvinceAdapter.getSelectedPosition() != INDEX_INVALID) {
                    mCityListView.setSelection(mProvinceAdapter.getSelectedPosition());
                }
            }
            updateTabVisible();
            updateIndicator();
        });
        mCityTv.setOnClickListener(v -> {
            tabIndex = INDEX_TAB_CITY;
            if (mCityAdapter != null) {
                mCityListView.setAdapter(mCityAdapter);
                if (mCityAdapter.getSelectedPosition() != INDEX_INVALID) {
                    mCityListView.setSelection(mCityAdapter.getSelectedPosition());
                }
            }
            updateTabVisible();
            updateIndicator();
        });
        mAreaTv.setOnClickListener(v -> {
            tabIndex = INDEX_TAB_AREA;
            if (mAreaAdapter != null) {
                mCityListView.setAdapter(mAreaAdapter);
                if (mAreaAdapter.getSelectedPosition() != INDEX_INVALID) {
                    mCityListView.setSelection(mAreaAdapter.getSelectedPosition());
                }
            }
            updateTabVisible();
            updateIndicator();
        });
        mCityListView.setOnItemClickListener((parent, view, position, id) -> selectedList(position));

        PickerUtils.setBackgroundAlpha(context, 0.5f);
        updateIndicator();
        updateTabsStyle(INDEX_INVALID);
        if (CityConfig.DATA_LOCATION == dataStyle) {
            setProvinceListData();
        } else {
            setViewState(VIEW_STATE_LOADING);
            this.mOnRequestListener = onRequestListener;
            if (mOnRequestListener != null) {
                mOnRequestListener.onRequest(REQUEST_TYPE_PROVINCE, "");
            }
        }
    }

    private void setCityAdapter(ProvinceBean provinceBean) {
        mCityAdapter = new CityAdapter(context, provinceBean.getCityList());
        //选中省份数据后更新市数据
        mHandler.sendMessage(Message.obtain(mHandler, INDEX_TAB_CITY, provinceBean.getCityList()));
    }

    private void setAreaAdapter(CityBean cityBean) {
        mAreaAdapter = new AreaAdapter(context, cityBean.getCityList());
        //选中省份数据后更新市数据
        mHandler.sendMessage(Message.obtain(mHandler, INDEX_TAB_AREA, cityBean.getCityList()));
    }

    private boolean isOnlineData() {
        int dataStyle = cityConfig.getDataStyle();
        return CityConfig.DATA_LOCATION != dataStyle;
    }

    private void selectedList(int position) {
        switch (tabIndex) {
            case INDEX_TAB_PROVINCE:
                ProvinceBean provinceBean = mProvinceAdapter.getItem(position);
                if (provinceBean != null) {
                    mProTv.setText(provinceBean.getName());
                    mCityTv.setText("请选择");
                    mProvinceAdapter.updateSelectedPosition(position);
                    mProvinceAdapter.notifyDataSetChanged();
                    int dataStyle = cityConfig.getDataStyle();
                    if (CityConfig.DATA_LOCATION == dataStyle) {
                        setCityAdapter(provinceBean);
                    } else {
                        //请求城市数据
                        setViewState(VIEW_STATE_LOADING);
                        if (mOnRequestListener != null) {
                            mOnRequestListener.onRequest(REQUEST_TYPE_CITY, provinceBean.getProvinceCode());
                        }
                    }
                }
                break;
            case INDEX_TAB_CITY:
                CityBean cityBean = mCityAdapter.getItem(position);
                if (cityBean != null) {
                    mCityTv.setText(cityBean.getName());
                    mAreaTv.setText("请选择");
                    mCityAdapter.updateSelectedPosition(position);
                    mCityAdapter.notifyDataSetChanged();
                    if (this.cityConfig != null && this.cityConfig.getShowType() == CityConfig.ShowType.PRO_CITY) {
                        callback(new DistrictBean());
                    } else {
                        int dataStyle = cityConfig.getDataStyle();
                        if (CityConfig.DATA_LOCATION == dataStyle) {
                            setAreaAdapter(cityBean);
                        } else {
                            //请求县区数据
                            setViewState(VIEW_STATE_LOADING);
                            if (mOnRequestListener != null) {
                                mOnRequestListener.onRequest(REQUEST_TYPE_DISTRICT, cityBean.getCityCode());
                            }
                        }
                    }
                }
                break;
            case INDEX_TAB_AREA:
                //返回选中的省市区数据
                DistrictBean districtBean = mAreaAdapter.getItem(position);
                if (districtBean != null) {
                    callback(districtBean);
                }
                break;
            default:
                break;
        }
    }

    /**
     * 设置默认的省份数据
     */
    private void setProvinceListData() {
        if (parseHelper != null) {
            provinceList = parseHelper.getProvinceBeanArrayList();
        }
        if (provinceList != null && !provinceList.isEmpty()) {
            mProvinceAdapter = new ProvinceAdapter(context, provinceList);
            mCityListView.setAdapter(mProvinceAdapter);
        }
    }

    public void setProvinceListData(List<ProvinceBean> listData) {
        provinceList = listData;
        if (provinceList != null && !provinceList.isEmpty()) {
            setViewState(VIEW_STATE_CONTENT);
            mProvinceAdapter = new ProvinceAdapter(context, provinceList);
            mCityListView.setAdapter(mProvinceAdapter);
        }
    }

    public void setCityListData(List<CityBean> listData) {
        cityList = listData;
        if (cityList != null && !cityList.isEmpty()) {
            setViewState(VIEW_STATE_CONTENT);
            mCityAdapter = new CityAdapter(context, cityList);
            mCityListView.setAdapter(mCityAdapter);
            mHandler.sendMessage(Message.obtain(mHandler, INDEX_TAB_CITY, cityList));
        } else {
            callback();
        }
    }

    public void setDistrictListData(List<DistrictBean> listData) {
        areaList = listData;
        if (areaList != null && !areaList.isEmpty()) {
            setViewState(VIEW_STATE_CONTENT);
            mAreaAdapter = new AreaAdapter(context, areaList);
            mCityListView.setAdapter(mAreaAdapter);
            mHandler.sendMessage(Message.obtain(mHandler, INDEX_TAB_AREA, areaList));
        } else {
            callback();
        }
    }

    /**
     * 初始化，默认解析城市数据，提交加载速度
     */
    public void init(Context context, String fileName) {
        this.context = context;
        if (parseHelper != null) {
            parseHelper = new CityParseHelper();
            //解析初始数据
            if (parseHelper.getProvinceBeanArrayList().isEmpty()) {
                parseHelper.initData(context, fileName);
            }
        }
    }

    /**
     * 更新选中城市下面的红色横线指示器
     */
    private void updateIndicator() {
        popview.post(() -> {
            switch (tabIndex) {
                case INDEX_TAB_PROVINCE:
                    tabSelectedIndicatorAnimation(mProTv).start();
                    break;
                case INDEX_TAB_CITY:
                    tabSelectedIndicatorAnimation(mCityTv).start();
                    break;
                case INDEX_TAB_AREA:
                    tabSelectedIndicatorAnimation(mAreaTv).start();
                    break;
                default:
                    break;
            }
        });
    }

    /**
     * tab 选中的红色下划线动画
     *
     * @param tab
     * @return
     */
    private AnimatorSet tabSelectedIndicatorAnimation(TextView tab) {
        ObjectAnimator xAnimator = ObjectAnimator.ofFloat(mSelectedLine, "X", mSelectedLine.getX(), tab.getX());

        final ViewGroup.LayoutParams params = mSelectedLine.getLayoutParams();
        ValueAnimator widthAnimator = ValueAnimator.ofInt(params.width, tab.getMeasuredWidth());
        widthAnimator.addUpdateListener(animation -> {
            params.width = (int) animation.getAnimatedValue();
            mSelectedLine.setLayoutParams(params);
        });

        AnimatorSet set = new AnimatorSet();
        set.setInterpolator(new FastOutSlowInInterpolator());
        set.playTogether(xAnimator, widthAnimator);

        return set;
    }

    public void showCityPicker(OnRequestListener onRequestListener) {
        initJDCityPickerPop(onRequestListener);
        if (!isShow()) {
            popwindow.showAtLocation(popview, Gravity.BOTTOM, 0, 0);
        }
    }

    private void hidePop() {
        if (isShow()) {
            popwindow.dismiss();
        }
    }

    private boolean isShow() {
        return popwindow.isShowing();
    }

    private void updateTabVisible() {
        mProTv.setVisibility(provinceList == null || provinceList.isEmpty() ? View.GONE : View.VISIBLE);
        mCityTv.setVisibility(cityList == null || cityList.isEmpty() ? View.GONE : View.VISIBLE);
        mAreaTv.setVisibility(areaList == null || areaList.isEmpty() ? View.GONE : View.VISIBLE);
    }

    /**
     * 选择回调
     *
     * @param districtBean
     */
    private void callback(DistrictBean districtBean) {

        ProvinceBean provinceBean = provinceList != null &&
                !provinceList.isEmpty() &&
                mProvinceAdapter != null &&
                mProvinceAdapter.getSelectedPosition() != INDEX_INVALID ?
                provinceList.get(mProvinceAdapter.getSelectedPosition()) : null;

        CityBean cityBean = cityList != null &&
                !cityList.isEmpty() &&
                mCityAdapter != null &&
                mCityAdapter.getSelectedPosition() != INDEX_INVALID ?
                cityList.get(mCityAdapter.getSelectedPosition()) : null;

        mBaseListener.onSelected(provinceBean, cityBean, districtBean);
        hidePop();
    }

    private void callback() {

        ProvinceBean provinceBean = provinceList != null &&
                !provinceList.isEmpty() &&
                mProvinceAdapter != null &&
                mProvinceAdapter.getSelectedPosition() != INDEX_INVALID ?
                provinceList.get(mProvinceAdapter.getSelectedPosition()) : null;

        CityBean cityBean = cityList != null &&
                !cityList.isEmpty() &&
                mCityAdapter != null &&
                mCityAdapter.getSelectedPosition() != INDEX_INVALID ?
                cityList.get(mCityAdapter.getSelectedPosition()) : null;

        mBaseListener.onSelected(provinceBean, cityBean, null);
        hidePop();
    }

    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case INDEX_INVALID:

                case INDEX_TAB_PROVINCE:
                    provinceList = (List<ProvinceBean>) msg.obj;
                    mProvinceAdapter.notifyDataSetChanged();
                    mCityListView.setAdapter(mProvinceAdapter);
                    break;

                case INDEX_TAB_CITY:
                    cityList = (List<CityBean>) msg.obj;
                    mCityAdapter.notifyDataSetChanged();
                    if (cityList != null && !cityList.isEmpty()) {
                        mCityListView.setAdapter(mCityAdapter);
                        tabIndex = INDEX_TAB_CITY;
                    }
                    break;

                case INDEX_TAB_AREA:
                    areaList = (List<DistrictBean>) msg.obj;
                    mAreaAdapter.notifyDataSetChanged();
                    if (areaList != null && !areaList.isEmpty()) {
                        mCityListView.setAdapter(mAreaAdapter);
                        tabIndex = INDEX_TAB_AREA;
                    }
                    break;
            }

            updateTabsStyle(tabIndex);
            updateIndicator();
            return true;
        }
    });

    /**
     * 设置选中的城市tab是否可见
     */
    private void updateTabsStyle(int tabIndex) {
        switch (tabIndex) {
            case INDEX_INVALID:

            case INDEX_TAB_PROVINCE:
                mProTv.setTextColor(Color.parseColor(colorAlert));
                mProTv.setVisibility(View.VISIBLE);
                mCityTv.setVisibility(View.GONE);
                mAreaTv.setVisibility(View.GONE);
                break;

            case INDEX_TAB_CITY:
                mProTv.setTextColor(Color.parseColor(colorSelected));
                mCityTv.setTextColor(Color.parseColor(colorAlert));
                mProTv.setVisibility(View.VISIBLE);
                mCityTv.setVisibility(View.VISIBLE);
                mAreaTv.setVisibility(View.GONE);
                break;

            case INDEX_TAB_AREA:
                mProTv.setTextColor(Color.parseColor(colorSelected));
                mCityTv.setTextColor(Color.parseColor(colorSelected));
                mAreaTv.setTextColor(Color.parseColor(colorAlert));
                mProTv.setVisibility(View.VISIBLE);
                mCityTv.setVisibility(View.VISIBLE);
                mAreaTv.setVisibility(View.VISIBLE);
                break;
        }
    }

    public interface OnRequestListener {
        void onRequest(@RequestType int requestType, String code);
    }
}
